

#include <string.h> 


#include "os_sync.h"
#include "os_mem.h"
#include "flash_device.h"
#include "flash_adv_cfg.h"

#include "log.h"

#define LOG0        LOG_INFO0
#define LOG1        LOG_INFO1

void *xflash_mutex_handle = NULL;
void xFLASH_init(void)
{
    if( os_mutex_create( &xflash_mutex_handle ) == false )
    {
        // print error 
        LOG0("tfs_flash_mutex_handle create FAIL!!!");
    }
}
static void xflash_mutex_take(void)
{
    if( os_mutex_take( xflash_mutex_handle, 500 ) == false )
    {
        LOG0("tfs_flash_mutex_handle take FAIL!!!");
    }
}
static void xflash_mutex_give(void)
{
    if( os_mutex_give( xflash_mutex_handle ) == false )
    {
        LOG0("tfs_flash_mutex_handle give FAIL!!!");
    }
}

void xFLASH_erase_sector(uint32_t addr)
{
    xflash_mutex_take();
    uint8_t prev_bp_lv = 0;
    flash_sw_protect_unlock_by_addr_locked(addr, &prev_bp_lv);
    flash_erase_locked( FLASH_ERASE_SECTOR, addr ); 
    flash_set_block_protect_locked(prev_bp_lv);
    xflash_mutex_give();
}
void xFLASH_write_data(uint32_t addr, uint8_t * pdata, uint32_t len)
{
    xflash_mutex_take();
    uint8_t prev_bp_lv = 0;
    flash_sw_protect_unlock_by_addr_locked(addr, &prev_bp_lv);
    flash_write_locked( addr, len, pdata ); 
    flash_set_block_protect_locked(prev_bp_lv);
    xflash_mutex_give();
}
void xFLASH_read_data(uint32_t addr, uint8_t * pdata, uint32_t len)
{
    xflash_mutex_take();
    if( len > 256 ) 
    {
        xflash_mutex_give();
        return; 
    }
    
    if( (addr & 0x03) == 0 ) 
    {
        if( len > 60 ) 
        {
            uint32_t counter = 0;
            flash_split_read_locked( addr, len, pdata, &counter); 
        }
        else 
        {
            flash_read_locked( addr , len, pdata );
        }
    }
    else 
    {
        uint32_t bytes_to_read = (4 + len + 3 ) & (~0x03);
        uint8_t buffer[256]; // 
        uint32_t counter = 0;
        uint32_t new_addr =  addr & (~0x03); 
        if( bytes_to_read > 60 ) 
        {
            flash_split_read_locked( new_addr, bytes_to_read, buffer, &counter); 
        }
        else 
        {
            flash_read_locked( new_addr , bytes_to_read, buffer );
        }
        memcpy( pdata, buffer + (addr & 0x03), len ); 
    }
    xflash_mutex_give();
}

